Texture2D ColorMap[2];

SamplerState ColorSampler : register( s0 );

cbuffer Light
{	
	float3 LightPosition;
	float3 LightDiffuseColor; // intensity multiplier
	float3 LightSpecularColor; // intensity multiplier
	float LightDistanceSquared;
	float3 LightAmbientColor;	
	bool LightTurnOn;
};

cbuffer Material
{
	float3 DiffuseColor;
	float3 EmissiveColor;
	float3 SpecularColor;
	float SpecularPower;
};

cbuffer cbChangesEveryFrame : register( b0 )
{
    matrix WorldMatrix;	
	float Transparent;
	int TexCount;
	float3 CameraPos;
};

cbuffer cbNeverChanges : register( b1 )
{
    matrix ViewMatrix;
};

cbuffer cbChangeOnResize : register( b2 )
{
    matrix ProjMatrix;
};

struct VS_Input
{
	float4 pos : POSITION;
	float4 norm : NORMAL;
	float2 tex0 : TEXCOORD0;
};

struct PS_Input
{
	float4 pos : SV_POSITION;
	float2 tex0 : TEXCOORD0;
	float4 worldPos : TEXCOORD1;
	float3 normal : TEXCOORD2;
};

PS_Input VS_Main(VS_Input vertex)
{	
	PS_Input vsOut = (PS_Input) 0;
	float4x4 viewProj = mul(ViewMatrix, ProjMatrix);
	float4 posWorld = mul(vertex.pos, WorldMatrix);
	vsOut.pos = mul(posWorld, viewProj);
	vsOut.tex0 = vertex.tex0;
	vsOut.normal = mul(vertex.norm, (float3x3)WorldMatrix);
	vsOut.worldPos = posWorld;
	return vsOut;
}

float4 PS_Main(PS_Input frag) : SV_TARGET
{
	float3 lightDir = normalize(frag.worldPos - LightPosition);
	float diffuse = saturate(dot(frag.normal, -lightDir));
	diffuse *= (LightDistanceSquared / dot(LightPosition - frag.worldPos, LightPosition - frag.worldPos));
	float3 h = normalize(normalize(CameraPos - frag.worldPos) - lightDir);
	float spec = pow(saturate(dot(h, frag.normal)), SpecularPower);
	float4 result;
	if(TexCount == 2)
	{
		float4 col1 = ColorMap[0].Sample(ColorSampler, frag.tex0);
		float4 col2 = ColorMap[1].Sample(ColorSampler, frag.tex0);		
		result = col1 * col2 * 2.0;
		result = saturate(result);
	}
	else if(TexCount == 1)
	{
		result = ColorMap[0].Sample(ColorSampler, frag.tex0);
	}
	else 
	{
		result = float4(0.5f, 0.5f, 0.5f, 1.0f);
	}
	result.a = Transparent;
	if(LightTurnOn)
	{
		result =  float4(saturate(LightAmbientColor +
					(result.xyz * DiffuseColor * LightDiffuseColor * diffuse * 0.6) + 
					(SpecularColor * LightSpecularColor * spec * 0.5)), result.w);
	}

	

	return result;
}

float4 PS_Solid(PS_Input frag) : SV_TARGET
{
	return float4(1,1,0,1);
}

BlendState EnableBlend
{
	BlendEnable[0] = TRUE;
	SrcBlend[0] = SRC_ALPHA;
	DestBlend[0] = INV_SRC_ALPHA;
	BlendOp[0] = ADD;
	SrcBlendAlpha[0] = ZERO;
	DestBlendAlpha[0] = ZERO;
	BlendOpAlpha[0] = ADD;	
};

RasterizerState DisableCulling
{
	CullMode=None;
};

RasterizerState CCWCulling
{
	CullMode=Front;
};

RasterizerState CWCulling
{
	CullMode=Back;
};

technique11 Alpha
{
	pass P0
	{		
		SetVertexShader(CompileShader(vs_5_0, VS_Main()));
		SetGeometryShader(NULL);
		SetPixelShader(CompileShader(ps_5_0, PS_Main()));		
		SetBlendState(EnableBlend, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF);
	}
}

technique11 Solid
{
	pass p0
	{
		SetVertexShader(CompileShader(vs_5_0, VS_Main()));
		SetGeometryShader(NULL);
		SetPixelShader(CompileShader(ps_5_0, PS_Solid()));
		
	}
}
